package org.particlethink.service.listen.listener;

import org.particlethink.entry.DeliverStatus;
import org.particlethink.entry.PlanTyp;
import org.particlethink.mapper.*;
import org.particlethink.model.*;
import org.particlethink.service.listen.event.OrderAllShipmentEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * 更新批次计划入库率
 */
@Component
public class UpdateOrderAllShipmentListener implements ApplicationListener<OrderAllShipmentEvent> {

    @Autowired
    private DeliverMapper deliverMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private PlanMaterialMapper planMaterialMapper;

    @Override
    public void onApplicationEvent(OrderAllShipmentEvent event) {
        Order order = event.getOrder();
        if (order == null) {
            return;
        }
        List<PlanMaterial> planMaterials = this.planMaterialMapper.selectByOrderID(order.getId());
        HashMap<Integer, Integer> objectObjectHashMap = new HashMap<>();
        planMaterials.forEach(planMaterial -> {
            int need = planMaterial.getExpectNum() - planMaterial.getCompleteNum();
            if (objectObjectHashMap.containsKey(planMaterial.getMaterialId())) {
                objectObjectHashMap.put(planMaterial.getMaterialId(), objectObjectHashMap.get(planMaterial.getMaterialId()) + need);
            } else {
                objectObjectHashMap.put(planMaterial.getMaterialId(), need);
            }
        });

        AtomicBoolean allShipment = new AtomicBoolean(true);

        objectObjectHashMap.forEach((integer, needCount) -> {
            if (needCount > 0) {
                allShipment.set(false);
            }
        });

        if (allShipment.get()) {
            if (order.getAllShipment()) {
                return;
            }
            order.setAllShipment(true);
            this.orderMapper.updateByPrimaryKey(order);
            return;
        }


        List<Deliver> delivers = this.deliverMapper.selectByOrderAndStatuses(order.getId(), Arrays.asList(DeliverStatus.UnChecked, DeliverStatus.UnConfirmed));

        if (delivers == null || delivers.isEmpty()) {
//            if (order.isAllShipment()) {
//                order.setAllShipment(false);
//                this.orderMapper.updateByPrimaryKey(order);
//            }
            return;
        }
        List<Integer> deliverIds = delivers.stream().map(Deliver::getId).distinct().collect(Collectors.toList());
        List<PlanMaterial> deliverPlanMaterials = this.planMaterialMapper.selectByPlanIDsAndTyp(deliverIds, PlanTyp.Deliver);

        deliverPlanMaterials.forEach(planMaterial -> {
            Integer need = objectObjectHashMap.get(planMaterial.getMaterialId());
            if (objectObjectHashMap.containsKey(planMaterial.getMaterialId())) {
                objectObjectHashMap.put(planMaterial.getMaterialId(), objectObjectHashMap.get(planMaterial.getMaterialId()) - need);
            }
        });


        allShipment.set(true);
        objectObjectHashMap.forEach((integer, needCount) -> {
            if (needCount > 0) {
                allShipment.set(false);
            }
        });

        if (allShipment.get()) {
            if (!order.getAllShipment()) {
                order.setAllShipment(true);
                this.orderMapper.updateByPrimaryKeySelective(order);
                return;
            }
            return;
        }

        if (order.getAllShipment()) {
            order.setAllShipment(false);
            this.orderMapper.updateByPrimaryKey(order);
        }
    }
}
